<?php
/**
 * DBShop 电子商务系统
 *
 * ==========================================================================
 * @link      https://www.dbshop.net/
 * @copyright 北京珑大钜商科技有限公司，并保留所有权利。
 * @license   https://www.dbshop.net/license.html License
 * ==========================================================================
 *
 * @author    静静的风 <baron@loongdom.cn>
 *
 */

namespace Goods\Repository;

use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\Query\Expr\Join;
use Goods\Entity\Goods;
use Goods\Entity\GoodsBrand;
use Goods\Entity\GoodsClass;
use Goods\Entity\GoodsDiscount;
use Goods\Entity\GoodsGroupPrice;
use Goods\Entity\GoodsImage;
use Goods\Entity\GoodsInClass;
use Goods\Entity\GoodsInTag;
use Goods\Entity\GoodsSalesRecord;
use Goods\Entity\GoodsStock;
use Goods\Repository\QuerySearch\GoodsSearch;

class GoodsRepository extends EntityRepository
{
    /**
     * 获取最大商品id
     * @return int|mixed|string
     * @throws \Doctrine\ORM\NoResultException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function getMaxGoodsId()
    {
        $query = $this->getEntityManager()->createQueryBuilder();
        $query->select('MAX(g.goodsId) as maxGoodsId')->from(Goods::class, 'g');

        return $query->getQuery()->getSingleScalarResult();
    }

    /**
     * 后台商品列表返回
     * @param array $search
     * @return \Doctrine\ORM\Query
     */
    public function findAllGoods($search = [])
    {
        $query = $this->getEntityManager()->createQueryBuilder()
            ->select('g', 'i.goodsThumbnailImage', 'c.className')
            ->from(Goods::class, 'g')
            ->leftJoin(GoodsImage::class, 'i', Join::WITH, 'g.goodsImageId=i.goodsImageId')
            ->leftJoin(GoodsClass::class, 'c', Join::WITH, 'g.classId=c.classId')
            ->orderBy('g.goodsId', 'DESC');

        $query = GoodsSearch::querySearch($search, $query);

        return $query->getQuery();
    }

    /**
     * 品牌商品列表
     * @param $brandId
     * @return \Doctrine\ORM\Query
     */
    public function findBrandGoods($brandId)
    {
        $query = $this->getEntityManager()->createQueryBuilder()
            ->select('g')
            ->from(Goods::class, 'g')
            ->where('g.brandId = :brandId')->setParameter('brandId', $brandId)
            ->orderBy('g.goodsId', 'DESC');

        return $query->getQuery();
    }

    /*==============================================下面为前台调用==============================================*/

    /**
     * 前台分类商品列表
     * @param array $search
     * @param int $userGroupId
     * @return \Doctrine\ORM\Query
     */
    public function findShopClassGoodsList($search = [], $userGroupId = 0)
    {
        $query = $this->getEntityManager()->createQueryBuilder()
            ->select('g', 'i.goodsThumbnailImage', 'c.classId', 'r.goodsSalesNum')
            ->from(Goods::class, 'g')
            ->leftJoin(GoodsImage::class, 'i', Join::WITH, 'g.goodsImageId=i.goodsImageId')
            ->innerJoin(GoodsSalesRecord::class, 'r', Join::WITH, 'g.goodsId = r.goodsId')
            ->innerJoin(GoodsInClass::class, 'c', Join::WITH, 'g.goodsId=c.goodsId')
            ->where('g.goodsState = :goodsState')->setParameter('goodsState', 1)
            ->orderBy('c.classGoodsRecommend', 'ASC')->addOrderBy('c.classGoodsSort', 'ASC');

        //如果会员组存在，则获取会员组价格
        if($userGroupId > 0) $query->addSelect('(SELECT p.userGroupPrice FROM '.GoodsGroupPrice::class.' AS p WHERE p.goodsId=g.goodsId AND p.userGroupId='.$userGroupId.') AS goodsGroupPrice');

        //排序
        if(isset($search['sort'])) {
            if(in_array($search['sort'], ['priceASC', 'priceDESC'])) $query->addOrderBy('g.goodsPrice', ($search['sort'] == 'priceASC' ? 'ASC' : 'DESC'));
            if(in_array($search['sort'], ['clickASC', 'clickDESC'])) $query->addOrderBy('g.goodsClick', ($search['sort'] == 'clickASC' ? 'ASC' : 'DESC'));
            if(in_array($search['sort'], ['timeASC', 'timeDESC'])) $query->addOrderBy('g.goodsAddTime', ($search['sort'] == 'timeASC' ? 'ASC' : 'DESC'));
        } else $query->addOrderBy('c.goodsId', 'DESC');

        //标签
        if(isset($search['tag'])) $query->innerJoin(GoodsInTag::class, 't', Join::WITH, 'g.goodsId=t.goodsId');

        $query = GoodsSearch::shopQuerySearch($search, $query);

        return $query->getQuery();
    }

    /**
     * 前台品牌商品列表
     * @param array $search
     * @param int $userGroupId
     * @return \Doctrine\ORM\Query
     */
    public function findShopBrandGoodsList($search = [], $userGroupId = 0)
    {
        $query = $this->getEntityManager()->createQueryBuilder()
            ->select(
                'g',
                'i.goodsThumbnailImage',
                'r.goodsSalesNum'
            )
            ->from(Goods::class, 'g')
            ->leftJoin(GoodsImage::class, 'i', Join::WITH, 'g.goodsImageId=i.goodsImageId')
            ->innerJoin(GoodsSalesRecord::class, 'r', Join::WITH, 'g.goodsId = r.goodsId')
            ->where('g.goodsState = :goodsState')->setParameter('goodsState', 1);

        //如果会员组存在，则获取会员组价格
        if($userGroupId > 0) $query->addSelect('(SELECT p.userGroupPrice FROM '.GoodsGroupPrice::class.' AS p WHERE p.goodsId=g.goodsId AND p.userGroupId='.$userGroupId.') AS goodsGroupPrice');

        //排序
        if(isset($search['sort'])) {
            if(in_array($search['sort'], ['priceASC', 'priceDESC'])) $query->addOrderBy('g.goodsPrice', ($search['sort'] == 'priceASC' ? 'ASC' : 'DESC'));
            if(in_array($search['sort'], ['clickASC', 'clickDESC'])) $query->addOrderBy('g.goodsClick', ($search['sort'] == 'clickASC' ? 'ASC' : 'DESC'));
            if(in_array($search['sort'], ['timeASC', 'timeDESC'])) $query->addOrderBy('g.goodsAddTime', ($search['sort'] == 'timeASC' ? 'ASC' : 'DESC'));
        } else $query->addOrderBy('g.goodsId', 'DESC');

        $query = GoodsSearch::shopBrandQuerySearch($search, $query);

        return $query->getQuery();
    }

    /**
     * 前台商品详情
     * @param $goodsId
     * @return mixed
     * @throws \Doctrine\ORM\NoResultException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function findShopGoodsInfo($goodsId)
    {
        $query = $this->getEntityManager()->createQueryBuilder();
        $query->select(
            'g',
            'i.goodsThumbnailImage', 'i.goodsImage',
            'r.goodsSalesNum',
            'b.brandName',
            'd.discountPrice', 'd.discountStartTime', 'd.discountEndTime', 'd.discountUserGroupType', 'd.discountUserGroup',
            's.stockNum', 's.stockShowState', 's.stockShow', 's.stockOutSetNum', 's.stockOutShow', 's.cartBuyMinNum', 's.cartBuyMaxNum'
        )
            ->from(Goods::class, 'g')
            ->leftJoin(GoodsImage::class, 'i', Join::WITH, 'g.goodsImageId=i.goodsImageId')
            ->innerJoin(GoodsSalesRecord::class, 'r', Join::WITH, 'g.goodsId = r.goodsId')
            ->innerJoin(GoodsDiscount::class, 'd', Join::WITH, 'g.goodsId = d.goodsId')
            ->innerJoin(GoodsStock::class, 's', Join::WITH, 'g.goodsId = s.goodsId')
            ->leftJoin(GoodsBrand::class, 'b', Join::WITH, 'g.brandId = b.brandId')
            ->where('g.goodsId = :goodsId')->setParameter('goodsId', $goodsId)
            ->andWhere('g.goodsState = :goodsState')->setParameter('goodsState', 1);

        return $query->getQuery()->getOneOrNullResult();
    }

    /**
     * 前台商品搜索
     * @param array $search
     * @param int $userGroupId
     * @return \Doctrine\ORM\Query
     */
    public function findShopSearchGoodsList($search = [], $userGroupId = 0)
    {
        $query = $this->getEntityManager()->createQueryBuilder()
            ->select('g', 'i.goodsThumbnailImage', 'r.goodsSalesNum')
            ->from(Goods::class, 'g')
            ->leftJoin(GoodsImage::class, 'i', Join::WITH, 'g.goodsImageId=i.goodsImageId')
            ->innerJoin(GoodsSalesRecord::class, 'r', Join::WITH, 'g.goodsId = r.goodsId')
            ->where('g.goodsState = :goodsState')->setParameter('goodsState', 1);

        //如果会员组存在，则获取会员组价格
        if($userGroupId > 0) $query->addSelect('(SELECT p.userGroupPrice FROM '.GoodsGroupPrice::class.' AS p WHERE p.goodsId=g.goodsId AND p.userGroupId='.$userGroupId.') AS goodsGroupPrice');

        //排序
        if(isset($search['sort'])) {
            if(in_array($search['sort'], ['priceASC', 'priceDESC'])) $query->addOrderBy('g.goodsPrice', ($search['sort'] == 'priceASC' ? 'ASC' : 'DESC'));
            if(in_array($search['sort'], ['clickASC', 'clickDESC'])) $query->addOrderBy('g.goodsClick', ($search['sort'] == 'clickASC' ? 'ASC' : 'DESC'));
            if(in_array($search['sort'], ['timeASC', 'timeDESC'])) $query->addOrderBy('g.goodsAddTime', ($search['sort'] == 'timeASC' ? 'ASC' : 'DESC'));
        } else $query->addOrderBy('g.goodsId', 'DESC');

        $query = GoodsSearch::shopSearchGoods($search, $query);

        return $query->getQuery();
    }

    /**
     * 随机商品，当商品数量比较小是，随机的数量不固定
     * @param $goodsNum
     * @param int $goodsId
     * @param int $userGroupId
     * @return int|mixed|string
     * @throws \Doctrine\ORM\NoResultException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function findShopRandGoods($goodsNum, $goodsId = 0, $userGroupId = 0)
    {
        $randGoodsId= floor(lcg_value() * $this->getMaxGoodsId());

        $query = $this->getEntityManager()->createQueryBuilder();
        $query->select('g', 'i.goodsThumbnailImage')
            ->from(Goods::class, 'g')->leftJoin(GoodsImage::class, 'i', Join::WITH, 'g.goodsImageId=i.goodsImageId')
            ->where('g.goodsState = :goodsState')->setParameter('goodsState', 1)
            ->andWhere('g.goodsId >= :randGoodsId')->setParameter('randGoodsId', $randGoodsId)->setMaxResults($goodsNum);

        if ($goodsId > 0) $query->andWhere('g.goodsId!= :goodsId')->setParameter('goodsId', $goodsId);

        //如果会员组存在，则获取会员组价格
        if($userGroupId > 0) $query->addSelect('(SELECT p.userGroupPrice FROM '.GoodsGroupPrice::class.' AS p WHERE p.goodsId=g.goodsId AND p.userGroupId='.$userGroupId.') AS goodsGroupPrice');

        return $query->getQuery()->getResult();
    }
}